package com.common.common.option;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.function.Consumer;

/**
 * 查询条件
 *
 * @author liujun
 * @date 2024/10/10
 */
@Data
@NoArgsConstructor
public class QueryCondition {
    private String queryKey;
    private Object queryValue;
    private List<QueryCondition> children;
    private String symbol;

    /**
     * 构造函数(构造一个单条件查询)
     *
     * @param queryKey   查询键
     * @param queryValue 查询值
     */
    public QueryCondition(String queryKey, Object queryValue) {
        this.queryKey = queryKey;
        this.queryValue = queryValue;
    }

    /**
     * 构造函数(构造一个复杂条件查询)
     *
     * @param symbol   连接符(or/and)
     * @param children 子查询条件
     */
    public QueryCondition(String symbol, List<QueryCondition> children) {
        this.symbol = symbol;
        this.children = children;
    }

    public <T> QueryWrapper<T> toQueryWrapper() {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        this.toQueryWrapper(queryWrapper, QueryConnector.OR.val().equalsIgnoreCase(this.symbol), this);
        return queryWrapper;
    }

    private <T> void toQueryWrapper(QueryWrapper<T> queryWrapper, boolean isOr, QueryCondition condition){
        if (condition == null) {
            return;
        }
        if (condition.isAloneCondition()) {
            if (isOr) {
                queryWrapper.or();
            }
            String connector = QueryConnector.SUFFIX_CONNECTOR.val();
            String queryKey = condition.getQueryKey();
            Object queryValue = condition.getQueryValue();
            int lastIndexOf = queryKey.lastIndexOf(connector);
            if (lastIndexOf <= 0 || lastIndexOf >= queryKey.length() - connector.length()) {
                return;
            }
            String compare = queryKey.substring(lastIndexOf + connector.length());
            String column = queryKey.substring(0, lastIndexOf);
            if (compare.equalsIgnoreCase(QuerySuffix.LIKE.val())) {
                queryWrapper.like(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.LEFT_LIKE.val())) {
                queryWrapper.likeLeft(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.RIGHT_LIKE.val())) {
                queryWrapper.likeRight(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.EQUAL.val())) {
                queryWrapper.eq(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.LESS.val())) {
                queryWrapper.lt(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.GREAT.val())) {
                queryWrapper.gt(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.LESS_EQUAL.val())) {
                queryWrapper.le(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.GREAT_EQUAL.val())) {
                queryWrapper.ge(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.NOT_EQUAL.val())) {
                queryWrapper.ne(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.IS_NULL.val())) {
                queryWrapper.isNull(column);
            } else if (compare.equalsIgnoreCase(QuerySuffix.NOTNULL.val())) {
                queryWrapper.isNotNull(column);
            } else if (compare.equalsIgnoreCase(QuerySuffix.IN.val())) {
                queryWrapper.in(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.NOT_IN.val())) {
                queryWrapper.notIn(column, queryValue);
            } else if (compare.equalsIgnoreCase(QuerySuffix.BETWEEN.val())) {
                queryWrapper.between(column, ((List<?>) queryValue).get(0), ((List<?>) queryValue).get(1));
            }
        } else if (condition.isComplexCondition()) {
            Consumer<QueryWrapper<T>> consumer = wrapper -> {
                for (QueryCondition child : condition.getChildren()) {
                    toQueryWrapper(wrapper, QueryConnector.OR.val().equalsIgnoreCase(condition.getSymbol()), child);
                }
            };
            if (isOr) {
                queryWrapper.or(consumer);
            } else {
                queryWrapper.and(consumer);
            }
        }
    }

    public boolean isAloneCondition() {
        return this.queryKey != null && !this.queryKey.isEmpty();
    }

    public boolean isComplexCondition() {
        return !this.isAloneCondition() && this.children != null && !this.children.isEmpty();
    }

}
